package top.buluoluo.productservice.dto.response;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import top.buluoluo.productservice.entity.ProductDiscount;
import top.buluoluo.productservice.enums.DiscountTypeMethod;
import top.buluoluo.productservice.enums.StatusMethod;
import top.buluoluo.productservice.enums.TargetTypeMethod;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * 商品折扣数据传输对象 (DTO)
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DiscountDTO {

    // 折扣ID
    private BigInteger id;

    // 商户ID
    private BigInteger merchantId;

    // 商户名称（额外字段）
    private String merchantName;

    // 折扣目标类型：SPU-商品SPU，SKU-商品SKU
    private String targetType;

    // 目标ID（SPU ID或SKU ID）
    private BigInteger targetId;

    // 目标名称（额外字段）
    private String targetName;

    // 折扣率（0.5表示5折）
    private BigDecimal discountRate;

    // 折扣类型：PERCENTAGE-百分比，FIXED-固定金额
    private String discountType;

    // 最小购买数量
    private Long minQuantity;

    // 最大购买数量
    private Long maxQuantity;

    // 折扣开始时间
    private Date startTime;

    // 折扣结束时间
    private Date endTime;

    // 状态：ACTIVE-启用，INACTIVE-禁用，PENDING-待审核
    private String status;

    // 状态描述（额外字段）
    private String statusDescription;

    // 创建人ID
    private BigInteger createdBy;

    // 创建人姓名（额外字段）
    private String createdByName;

    // 更新人ID
    private BigInteger updatedBy;

    // 更新人姓名（额外字段）
    private String updatedByName;

    // 创建时间
    private LocalDateTime createdAt;

    // 更新时间
    private LocalDateTime updatedAt;

    // 是否有效（计算字段）
    private Boolean isValid;

    // 剩余时间（计算字段）
    private Long remainingHours;

    /**
     * 从实体转换为DTO
     */
    public static DiscountDTO fromEntity(ProductDiscount entity) {
        return DiscountDTO.builder()
                .id(entity.getId())
                .merchantId(entity.getMerchantId())
                .targetType(entity.getTargetType() != null ? entity.getTargetType().name() : null)
                .targetId(entity.getTargetId())
                .discountRate(entity.getDiscountRate())
                .discountType(entity.getDiscountType() != null ? entity.getDiscountType().name() : null)
                .minQuantity(entity.getMinQuantity())
                .maxQuantity(entity.getMaxQuantity())
                .startTime(entity.getStartTime())
                .endTime(entity.getEndTime())
                .status(entity.getStatus() != null ? entity.getStatus().name() : null)
                .createdBy(entity.getCreatedBy())
                .updatedBy(entity.getUpdatedBy())
                .createdAt(entity.getCreatedAt())
                .updatedAt(entity.getUpdatedAt())
                .build();
    }

    /**
     * 转换为实体
     */
    public ProductDiscount toEntity() {
        ProductDiscount entity = new ProductDiscount();
        entity.setId(this.id);
        entity.setMerchantId(this.merchantId);
        entity.setTargetType(this.targetType != null ? TargetTypeMethod.valueOf(this.targetType) : null);
        entity.setTargetId(this.targetId);
        entity.setDiscountRate(this.discountRate);
        entity.setDiscountType(this.discountType != null ? DiscountTypeMethod.valueOf(this.discountType) : null);
        entity.setMinQuantity(this.minQuantity);
        entity.setMaxQuantity(this.maxQuantity);
        entity.setStartTime(this.startTime);
        entity.setEndTime(this.endTime);
        entity.setStatus(this.status != null ? StatusMethod.valueOf(this.status) : null);
        entity.setCreatedBy(this.createdBy);
        entity.setUpdatedBy(this.updatedBy);
        entity.setCreatedAt(this.createdAt);
        entity.setUpdatedAt(this.updatedAt);
        return entity;
    }

    /**
     * 验证折扣有效性
     */
    public void validate() {
        // 折扣率验证
        if (discountRate == null) {
            throw new IllegalArgumentException("折扣率不能为空");
        }
        if (discountRate.compareTo(BigDecimal.ZERO) <= 0 || discountRate.compareTo(BigDecimal.ONE) > 0) {
            throw new IllegalArgumentException("折扣率必须在0和1之间");
        }

        // 时间范围验证
        if (startTime != null && endTime != null && startTime.after(endTime)) {
            throw new IllegalArgumentException("折扣开始时间不能晚于结束时间");
        }

        // 数量范围验证
        if (minQuantity != null && maxQuantity != null && minQuantity > maxQuantity) {
            throw new IllegalArgumentException("最小数量不能大于最大数量");
        }

        // 目标类型验证
        if (targetType == null) {
            throw new IllegalArgumentException("折扣目标类型不能为空");
        }

        // 目标ID验证
        if (targetId == null) {
            throw new IllegalArgumentException("目标ID不能为空");
        }
    }

    /**
     * 检查折扣是否有效（计算字段）
     */
    public boolean isCurrentlyValid() {
        if (status == null || !status.equals("ACTIVE")) {
            return false;
        }

        Date now = new Date();
        if (startTime != null && now.before(startTime)) {
            return false;
        }

        if (endTime != null && now.after(endTime)) {
            return false;
        }

        return true;
    }

    /**
     * 计算剩余时间（小时）
     */
    public Long calculateRemainingHours() {
        if (endTime == null || !isCurrentlyValid()) {
            return null;
        }

        long diffMillis = endTime.getTime() - System.currentTimeMillis();
        return diffMillis / (1000 * 60 * 60);
    }

    /**
     * 获取折扣描述
     */
    @JsonProperty("discountDescription")//Jackson 会自动把get和is方法返回的值映射为JSON属性，在这里显示声明JSON键名
    public String getDiscountDescription() {
        if (discountType == null || discountRate == null) {
            return "未知折扣";
        }

        if ("PERCENTAGE".equals(discountType)) {
            return String.format("%.0f折", discountRate.multiply(BigDecimal.TEN).floatValue());
        } else {
            return String.format("立减¥%.2f", discountRate);
        }
    }

    /**
     * 获取状态描述
     */
    @JsonProperty("statusDescription")
    public String getStatusDescription() {
        if (status == null) return "未知状态";

        switch (status) {
            case "ACTIVE":
                return "生效中";
            case "INACTIVE":
                return "已禁用";
            case "PENDING":
                return "待审核";
            default:
                return "未知状态";
        }
    }
}
